package com.jackrain.nea.fc.dl.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.TypeUtils;
import com.jackrain.nea.common.PostHandleEvent;
import com.jackrain.nea.common.QueryDLUtil;
import com.jackrain.nea.config.PropertiesConf;
import com.jackrain.nea.core.redis.RedisObjectSerializer;
import com.jackrain.nea.dl.common.utils.esutil.ConvertQueryListUtil;
import com.jackrain.nea.dl.common.utils.esutil.ElasticsearchUtil;
import com.jackrain.nea.exception.NDSException;
import com.jackrain.nea.fc.dl.api.ViewDLQueryCmd;
import com.jackrain.nea.fc.dl.mapper.ViewDLPurOrderMapper;
import com.jackrain.nea.fc.dl.api.ViewDLPurOrderSaveCmd;
import com.jackrain.nea.sys.CommandAdapter;
import com.jackrain.nea.util.ApplicationContextHandle;
import com.jackrain.nea.util.ReferenceUtil;
import com.jackrain.nea.util.RuntimeCompute;
import com.jackrain.nea.util.ValueHolder;
import com.jackrain.nea.web.face.User;
import com.jackrain.nea.web.query.DefaultWebEvent;
import com.jackrain.nea.web.query.QuerySessionImpl;
import com.jackrain.nea.web.security.Security4Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

/**
 * 采购订单 F4->中间表->FC
 *
 * @author wuwenxue
 * @date 2018/05/17
 **/
@Slf4j
@Component
@Service(protocol = "dubbo", validation = "true", version = "1.0", group = "cp")
public class ViewDLPurOrderSaveCmdImpl extends CommandAdapter implements ViewDLPurOrderSaveCmd {

    @Autowired
    PostHandleEvent postHandleEvent;

    @Autowired
    private ElasticsearchUtil esUtil;

    @Autowired
    private ConvertQueryListUtil convertQLUtil;

    @Autowired
    private PropertiesConf pconf;

    private RedisObjectSerializer serializer = new RedisObjectSerializer();

    @Reference(group = "dl", version = "1.0")
    private ViewDLQueryCmd viewDLQueryCmd;

    @Override
    public ValueHolder execute(HashMap map) throws NDSException {

        ValueHolder vh = new ValueHolder();
        JSONObject param = JSON.parseObject(JSON.toJSONStringWithDateFormat(map.get("param"),
                "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteMapNullValue), Feature.OrderedField);
        log.info("ViewDLPurOrderSaveCmdImpl--param-->{}",param);

        if (null == param || param.size() == 0) {
            throw new NDSException("参数格式错误！");
        }

        ViewDLPurOrderMapper viewDLPurOrderMapper = ApplicationContextHandle.getBean(ViewDLPurOrderMapper.class);

        JSONArray paramArray = param.getJSONArray("data");

        JSONArray errorArray = new JSONArray();
        JSONArray successIds = new JSONArray();
        JSONArray spendTimeArray = new JSONArray();
        for (int i = 0; i < paramArray.size(); i++) {
            JSONObject errorJson = new JSONObject();
            JSONObject tranJson = paramArray.getJSONObject(i);

            JSONObject zbJS = tranJson.getJSONObject("DL_T_PUR_ORDER_TRANSFER");

            /*************处理明细表数据************/
            try {
                JSONObject spendTime = new JSONObject();
                Long retObjid = null;
                int status = 0;
                String userName = zbJS.getString("OPR_ECODE");
                String idList = zbJS.getString("IDLIST");
                int autoCheck = zbJS.getInteger("AUTO_CHECK");
                String bill_No = zbJS.getString("BILL_NO");

                String field = "ID,STATUS";
                JSONObject whereJS = new JSONObject();
                whereJS.put("BILL_NO", bill_No);

                HashMap isExist = QueryDLUtil.queryDL("DL_B_PUR_ORDER", field, whereJS);
                if (null != isExist && isExist.size() > 0) {
                    status = TypeUtils.castToInt(isExist.get("STATUS"));
                    retObjid = TypeUtils.castToLong(isExist.get("ID"));
                }


//                String esIndex = pconf.getProperty("DL_B_PUR_ORDER");
//                JSONObject jsonObject = es(bill_No, esIndex);
//                List<Long> longs = convertQLUtil.selectId(jsonObject.toString());
//                if (null != longs && longs.size() > 0) {
//                    retObjid = longs.get(0);
//                    JSONObject source = billdata(jsonObject);
//                    status = source.getInteger("STATUS");
//                }

                if (null != retObjid && retObjid > 0 && autoCheck != 1) {
                    successIds.add(idList);
                    continue;
                }

                if (2 == status && 1 == autoCheck) {
                    successIds.add(idList);
                    continue;
                }

                if (null == userName) {
                    userName = "root";
                }
                User user = Security4Utils.getUser(userName);

                if (null == retObjid || retObjid <= 0) {
                    long saveStartTime = System.currentTimeMillis();
                    JSONObject resultJson = purOrderSaveData(tranJson, viewDLPurOrderMapper, user);
                    QuerySessionImpl querySession = new QuerySessionImpl(user);
                    DefaultWebEvent event = new DefaultWebEvent("dlPurOrder",
                            new HashMap(16));
                    event.put("param", resultJson);
                    event.setParameter("isSendMq", "N");
                    querySession.setEvent(event);

                    JSONObject retJo = postHandleEvent.executePostHandle(resultJson, querySession, event, "save");
                    double saveEndTime = (double) (System.currentTimeMillis() - saveStartTime) / 1000.0D;
                    spendTime.put("saveTime", saveEndTime);
                    spendTime.put("saveRetData", retJo);
                    log.info("retJo=====>" + retJo.toString());
                    if (!retJo.containsKey("code")){
                        throw new NDSException("保存返回值有误！无code");
                    }
                    if (retJo.containsKey("code") && (int) retJo.get("code") != 0) {
                        errorJson.put("key", idList);
                        if (null == retJo.get("message")) {
                            errorJson.put("message", "采购订单保存调用异常");
                        } else {
                            errorJson.put("message", "采购订单保存调用异常->" + retJo.get("message"));
                        }
                        errorArray.add(errorJson);
                        continue;
                    }
                    JSONObject retData = retJo.getJSONObject("data");
                    retObjid = retData.getLong("objid");
                }

                if (1 == autoCheck) {
                    long subStartTime = System.currentTimeMillis();
                    QuerySessionImpl querySession = new QuerySessionImpl(user);
                    DefaultWebEvent event = new DefaultWebEvent("dlPurOrder", new HashMap(16));
                    String notic = "com.jackrain.nea.dl.pur.api.order.PurOrderSubmitCmd:1.0:dl";
                    JSONObject resultJson = new JSONObject();
                    resultJson.put("objid", retObjid);
                    resultJson.put("table", "DL_B_PUR_ORDER");
                    event.setParameter("isSendMq", "Y");
                    event.put("param", resultJson);
                    querySession.setEvent(event);

                    JSONObject retSubJo = postHandleEvent.executePostHandle(resultJson, querySession, event, "submit");
                    double subEndTime = (double) (System.currentTimeMillis() - subStartTime) / 1000.0D;
                    spendTime.put("subEndTime", subEndTime);
                    log.info("retSubJo=====>" + retSubJo);
                    if (retSubJo.containsKey("code") && (int) retSubJo.get("code") != 0) {
                        errorJson.put("key", idList);
                        if (null == retSubJo.get("message")) {
                            errorJson.put("message", "标准服务调用异常");
                        } else {
                            errorJson.put("message", retSubJo.get("message"));
                        }
                        errorArray.add(errorJson);
                        continue;
                    }
                }
                successIds.add(idList);
                spendTimeArray.add(spendTime);
            } catch (Exception e) {
                String error = "";
                if ((e instanceof NDSException)) {
                    error = e.getMessage();
                } else {
                    StringWriter sw = new StringWriter();
                    PrintWriter pw = new PrintWriter(sw);
                    e.printStackTrace(pw);
                    error = sw.toString();
                }
                String idList = zbJS.getString("IDLIST");
                errorJson.put("key", idList);
                errorJson.put("message", error);
                errorArray.add(errorJson);
            }
        }

        if (errorArray.size() > 0) {
            vh.put("error", errorArray);
            vh.put("code", -1);
        } else {
            vh.put("code", 0);
        }
        vh.put("successIds", successIds);
        vh.put("spendTime", spendTimeArray);
        return vh;
    }

    private JSONObject purOrderSaveData(JSONObject tranJson, ViewDLPurOrderMapper viewDLPurOrderMapper, User user)
            throws Exception {
        JSONObject zbJS = tranJson.getJSONObject("DL_T_PUR_ORDER_TRANSFER");
        JSONArray itemJS = tranJson.getJSONArray("DL_T_PUR_ORDER_ITEM_TRANSFER");
        for (int j = 0; j < itemJS.size(); j++) {
            JSONObject itemJson = itemJS.getJSONObject(j);
            itemJson.put("ID", -1);
            itemJson.put("ISACTIVE", "Y");

            //商品ID
            if (null != itemJson.getString("PS_C_SKU_ECODE")) {
                String skuEcode = itemJson.getString("PS_C_SKU_ECODE");
                HashMap h = viewDLPurOrderMapper.selSkuData(skuEcode);

                if (null != h && h.size() > 0) {
                    //条码ID
                    itemJson.put("PS_C_SKU_ID", h.get("ID"));
                } else {
                    throw new NDSException("SKU 查询为空！  sku编码：" + skuEcode);
                }
            }
        }

        /*************处理主表数据************/
        JSONObject newzbJson = new JSONObject();
        Set<String> keySet = zbJS.keySet();
        for (String key : keySet) {
            if ("OPR_ECODE".equals(key) || "IDLIST".equals(key) || "AUTO_CHECK".equals(key)) {
                continue;
            } else {
                newzbJson.put(key, zbJS.get(key));
            }
        }

        if (zbJS.containsKey("CP_C_SUPPLIER_ECODE") && (null != zbJS.getString("CP_C_SUPPLIER_ECODE"))) {
            String ecode = zbJS.getString("CP_C_SUPPLIER_ECODE");
            HashMap h = viewDLPurOrderMapper.selSupplierData(ecode);
            if (null != h && h.size() > 0) {
                //供应商ID
                newzbJson.put("CP_C_SUPPLIER_ID", h.get("ID"));
            } else {
                throw new NDSException("供应商档案 查询为空  编码:" + ecode);
            }
        }
        if (zbJS.containsKey("CP_C_STORE_ECODE") && (null != zbJS.getString("CP_C_STORE_ECODE"))) {
            String ecode = zbJS.getString("CP_C_STORE_ECODE");
            HashMap h = viewDLPurOrderMapper.selStoreData(ecode);
            if (null != h && h.size() > 0) {
                //店仓ID
                newzbJson.put("CP_C_STORE_ID", h.get("ID"));
            } else {
                throw new NDSException("店仓档案 查询为空_编码:" + ecode);
            }
        }

        //需求单号
        String reqNo = zbJS.getString("DL_B_PUR_REQ_NO");

        if (null != reqNo) {
            String espurreqIndex = pconf.getProperty("DL_B_PUR_REQ");
            JSONObject jsonObject = es(reqNo, espurreqIndex);
            List<Long> reqIdList = convertQLUtil.selectId(jsonObject.toString());
            Long reqId = null;
            if (null != reqIdList && reqIdList.size() > 0) {
                reqId = reqIdList.get(0);
            }
            newzbJson.put("DL_B_PUR_REQ_ID", reqId);
        }

        //采购原因
        String purReasonEcode = zbJS.getString("PUR_REASON");
        if (null != purReasonEcode) {

            JSONObject paramObject1 = new JSONObject();
            String sql = "SELECT B.ID AS BILLDIM_ITEM_ID " +
                    "FROM DL_C_BILLDIM A,DL_C_BILLDIM_ITEM B " +
                    "WHERE B.DL_C_BILLDIM_ID=A.ID AND A.TAG='PUR_REASON' AND B.ECODE='" + purReasonEcode + "'";
            paramObject1.put("dlsql", sql);

            HashMap queryDlmap = new HashMap(16);
            queryDlmap.put("param", paramObject1);
            Object o = ReferenceUtil.refer(ApplicationContextHandle.getApplicationContext(),
                    "com.jackrain.nea.fc.dl.api.ViewDLQueryCmd",
                    "dl", "1.0");
            ValueHolder result = ((ViewDLQueryCmd) o).execute(queryDlmap);

            JSONObject selectMenuType = result.toJSONObject();
            byte[] dlbyte = selectMenuType.getString("dlLsit").getBytes("ISO-8859-1");
            List<HashMap> typeIDList = (List<HashMap>) serializer.deserialize(dlbyte);

            Long purReasonId = null;
            if (null != typeIDList && typeIDList.size() > 0) {
                HashMap purReasonHash = typeIDList.get(0);
                purReasonId = TypeUtils.castToLong(purReasonHash.get("BILLDIM_ITEM_ID"));
            }

            if (null != purReasonId) {
                newzbJson.put("PUR_REASON", purReasonId);
            }
        }

        newzbJson.put("OWNERID", user.getId());

        JSONObject fixColumn = new JSONObject();
        fixColumn.put("DL_B_PUR_ORDER", newzbJson);
        fixColumn.put("DL_B_PUR_ORDER_ITEM", itemJS);

        JSONObject resultJson = new JSONObject();
        resultJson.put("objid", -1);
        resultJson.put("IS_F4CHECK", "N");
        resultJson.put("fixcolumn", fixColumn);
        resultJson.put("table", "DL_B_PUR_ORDER");

        log.info("resultJson==>" + resultJson.toString());

        return resultJson;
    }


    /**
     * ES查询
     *
     * @param billNo 单据编号
     * @return id
     */
    public JSONObject es(String billNo, String esIndex) {
        JSONObject bill_no = esUtil.generateMatch("BILL_NO", billNo);
        List<JSONObject> terms = esUtil.packageTerm(bill_no);
//        List<Long> longs = null;
        JSONObject jsonObject = null;
        try {
            jsonObject = esUtil.searchAllDataByTerms(esIndex,
                    esIndex, "1", "10000", terms);
            log.debug("es_jsonObject->" + jsonObject);
//            longs = convertQLUtil.selectId(jsonObject.toString());
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        return jsonObject;
    }

    private JSONObject billdata(JSONObject esData) {
        JSONObject hits = esData.getJSONObject("hits");
        JSONArray hitsArray = hits.getJSONArray("hits");
        JSONObject sourceJson = hitsArray.getJSONObject(0);

        JSONObject source = sourceJson.getJSONObject("_source");

        return source;
    }
}
